<template>
    <section>
        <tinymce-editor :id="domId" v-model="myContent" :init="init"></tinymce-editor>
    </section>
</template>

<script>
import tinymce from 'tinymce/tinymce';
import tinymceEditor from '@tinymce/tinymce-vue';

import 'tinymce/themes/silver';
import 'tinymce/plugins/image'; // 插入上传图片插件
import 'tinymce/plugins/media'; // 插入视频插件
import 'tinymce/plugins/table'; // 插入表格插件
import 'tinymce/plugins/lists'; // 列表插件
import 'tinymce/plugins/wordcount'; // 字数统计插件
import 'tinymce/plugins/fullscreen'; // 全屏插件
import 'tinymce/plugins/preview'; // 预览插件
import 'tinymce/plugins/code'; // 查看源代码
import 'tinymce/plugins/autosave'; // 自动存稿
import 'tinymce/plugins/link'; // 超链接
import 'tinymce/plugins/codesample'; // 代码
require('P/static/tinymce/plugins/indent2em'); // 手动下载插件-缩进
require('P/static/tinymce/plugins/lineheight'); // 手动下载插件-行高

import { getCurrentInstance, reactive, ref, toRefs, watch } from 'vue';
import * as qiniu from 'qiniu-js';

export default {
    name: 'Tinymce',
    components: {
        tinymceEditor
    },
    props: {
        // v-model 实现方式
        modelValue: {
            type: String,
            default: ''
        },
        content: {
            type: String
        },
        config: {
            type: Object,
            default: () => {}
        }
    },
    emits: ['update:modelValue'],
    setup(props, context) {
        const { proxy } = getCurrentInstance();

        let domId = ref('J-tinymce' + Math.ceil(Math.random() * 10000));
        let myContent = ref(props.content);
        let init = ref({});
        let myConfig = reactive({
            base_url: 'static/tinymce', // 定义公用路径
            auto_focus: false,
            language_url: 'static/tinymce/langs/zh_CN.js',
            language: 'zh_CN',
            skin_url: 'static/tinymce/skins/ui/oxide', // skin路径，注意这个，很多网上教程都是skins/oxide、oxide-dark，但是发现其实并没有这个玩意儿
            height: 900, // 编辑器高度
            plugins:
                'code lists image media table wordcount preview autosave link indent2em lineheight codesample fullscreen emoticons insertdatetime',
            toolbar: [
                'code | undo redo restoredraft preview | lists image media table insertdatetime | removeformat link  codesample  | fullscreen | indent2em bullist numlist outdent indent',
                'emoticons | formatselect | fontselect | fontsizeselect | bold italic underline strikethrough blockquote | lineheight forecolor backcolor | alignleft aligncenter alignright alignjustify '
            ],
            branding: false, // 是否禁用“Powered by TinyMCE”
            menubar: false, // 顶部菜单栏显示
            convert_urls: false, // 禁止自动转换
            fontsize_formats: '12px 14px 16px 18px 24px 36px 48px 56px 72px', //字体大小自定义设置
            lineheight_val: '0.1 0.3 0.5 0.8 1 1.5 1.6 1.75 1.8 2 3 4 5',
            // FontSelect
            font_formats: `
                        微软雅黑=微软雅黑;
                        苹方=苹方;
                        宋体=宋体;
                        黑体=黑体;
                        仿宋=仿宋;
                        楷体=楷体;
                        隶书=隶书;
                        幼圆=幼圆;
                        Andale Mono=andale mono,times;
                        Arial=arial, helvetica,
                        sans-serif;
                        Arial Black=arial black, avant garde;
                        Book Antiqua=book antiqua,palatino;
                        Comic Sans MS=comic sans ms,sans-serif;
                        Courier New=courier new,courier;
                        Georgia=georgia,palatino;
                        Helvetica=helvetica;
                        Impact=impact,chicago;
                        Symbol=symbol;
                        Tahoma=tahoma,arial,helvetica,sans-serif;
                        Terminal=terminal,monaco;
                        Times New Roman=times new roman,times;
                        Trebuchet MS=trebuchet ms,geneva;
                        Verdana=verdana,geneva;
                        Webdings=webdings;
                        Wingdings=wingdings,zapf dingbats`,

            // 自定义文件上传回调，支持图片、视频
            file_picker_callback(callback, value, meta) {
                if (meta.filetype === 'image') {
                    // 创建一个隐藏的type=file的文件选择input
                    let input = document.createElement('input');
                    input.setAttribute('type', 'file');
                    // 打开上传弹窗
                    input.click();

                    input.onchange = function () {
                        let file = this.files[0]; // 只选取第一个文件。如果要选取全部，后面注意做修改

                        proxy.$utils.validateImg(file).then((status) => {
                            if (status) {
                                proxy.$http.get(proxy.$config.upload.uploadToken).then((res) => {
                                    let key = Date.now() + '_' + file.name;
                                    let token = res.data.uploadToken;
                                    let domain = res.data.domain;
                                    let config = { useCdnDomain: true, region: null };
                                    let putExtra = { fname: '', params: {}, mimeType: [] };

                                    let observable = qiniu.upload(
                                        file,
                                        key,
                                        token,
                                        putExtra,
                                        config
                                    );

                                    observable.subscribe({
                                        next() {},
                                        error() {},
                                        complete(data) {
                                            let image_url = 'http://' + domain + '/' + data.key;
                                            let url = proxy.$utils.splicingImageUrl(image_url);
                                            callback(url);
                                        }
                                    });
                                });
                            }
                        });
                    };
                } else if (meta.filetype === 'media') {
                    console.log(1111);
                }
            }
        });

        init.value = Object.assign(myConfig, props.config);

        watch(props, (newVal, oldVal) => {
            myContent.value = newVal.modelValue;
        });
        watch(myContent, (newVal, oldVal) => {
            context.emit('update:modelValue', newVal);
        });

        return {
            domId,
            myContent,
            init
        };
    }
};
</script>

<style>
.tox-silver-sink {
    z-index: 9999 !important;
}
.tox-tinymce-aux {
    z-index: 709826033 !important;
}
.tox-tinymce-inline {
    z-index: 709826033 !important;
}
</style>
